package de.au.fi.imp.reader.yahoodata;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.StringTokenizer;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import de.au.fi.calc.CalcHelper;

public class YahooDataReader {
	
	Logger log = LoggerFactory.getLogger(this.getClass());

	static String baseUrl = "http://finance.yahoo.com/d/quotes.csv?s=%s&f=%s";

	public YahooDataReader() {
	}

	public enum QueryTags {
		ASK("a"), DIVIDEND_DIV_SHARE("d"), EARNINGS_DIV_SHARE("e"), EPSAJ("e7"), EPSNJ(
				"e8"), WEEK52_LOW("j"), WEEK52_HIGH("k"), INFO("i"), MARKT_CAP(
				"j1"), EBITDA("j4"), NAME("n"), NOTES("n4"), KGV("r"), DIVIDEND_PAY_DATE(
				"r1"), PEG_RATION("r5"), PRICE_DIV_EPS_AJ("r6"), PRICE_DIV_EPS_NJ(
				"r7"), TICKER("s"), TARGET_PRICE_1J("t8"), DIVIDEND_YIELD("y"), KURS_NOW(
				"l1");

		String tag;

		QueryTags(String tag) {
			this.tag = tag;
		}

		public String getTag() {
			return this.tag;
		}
	}

	public static String getTagsString(QueryTags... queryTags) {
		String tags = "";
		for (QueryTags queryTag : queryTags)
			tags = tags.concat(queryTag.getTag());
		return tags;
	}

	public static String getTickerString(String... tickers) {
		String symbolString = "";
		for (String symbol : tickers) {
			if (!symbolString.isEmpty())
				symbolString = symbolString.concat("+");
			if(symbol.startsWith("^"))
				symbol = "@"+symbol;
			symbolString = symbolString.concat(symbol);
		}
		return symbolString;
	}

	public static String getQueryForTickersAndTags(String tickers, String tags) {
		return String.format(baseUrl, tickers, tags);
	}

	private static String getBasicQueryForTickers(String... tickers) {
		String tickerString = getTickerString(tickers);
		String tagString = getTagsString(QueryTags.TICKER, QueryTags.NAME,
				QueryTags.KURS_NOW, QueryTags.MARKT_CAP, QueryTags.KGV,
				QueryTags.EBITDA, QueryTags.EPSAJ, QueryTags.EPSNJ);
		return getQueryForTickersAndTags(tickerString, tagString);
	}

	public List<String> getStocksWithBasicData(String... tickers)
			throws Exception {
		return queryYahoo(getBasicQueryForTickers(tickers));
	}

	public List<String> getStocks(String tickers, String tags) throws Exception {
		return queryYahoo(getQueryForTickersAndTags(tickers, tags));
	}

	public List<String> queryYahoo(String query) throws Exception {
		System.out.println(query);
		URL url = new URL(query);

		URLConnection conn = url.openConnection();

		BufferedReader in = new BufferedReader(new InputStreamReader(
				conn.getInputStream()));
		List<String> stocksAsStrings = new ArrayList<String>();
		String line;
		while ((line = in.readLine()) != null && !line.isEmpty())
			stocksAsStrings.add(line);
		log.debug("Returning {} strings for query {}", stocksAsStrings.size(), query);
		return stocksAsStrings;
	}

	public List<Double> getHistoricKurse(String ticker) {
		URL url;

		Calendar cal = Calendar.getInstance();
		cal.setTime(new Date());
		int day = cal.get(Calendar.DAY_OF_MONTH);
		int month = cal.get(Calendar.MONTH);
		int year = cal.get(Calendar.YEAR);

		cal.add(Calendar.MONTH, -6);
		int endMonth = cal.get(Calendar.MONTH);
		int endYear = cal.get(Calendar.YEAR);

		List<String> data;
		try {
			url = new URL("http://ichart.finance.yahoo.com/table.csv?s=" + ticker
					+ "&b=" + day + "&a=" + month + "&c=" + (year - 1) + "&e="
					+ day + "&d=" + endMonth + "&f=" + endYear + "&g=d");

			URLConnection conn = url.openConnection();

			BufferedReader in = new BufferedReader(new InputStreamReader(
					conn.getInputStream()));

			data = new ArrayList<String>();
			String line;
			boolean first = true;
			while ((line = in.readLine()) != null) {
				if (first)
					first = false;
				else
					data.add(line);
			}
			return Arrays.asList(getKurs(data.get(0)),
					getKurs(data.get(data.size() - 1)));
		} catch (MalformedURLException e) {
			log.error("Error", e);
		} catch (IOException e) {
			log.error("Error", e);
		}
		return null;
	}

	private Double getKurs(String string) {
		List<String> data = new ArrayList<String>();
		StringTokenizer st = new StringTokenizer(string, ",");
		while (st.hasMoreElements())
			data.add((String) st.nextElement());
			return CalcHelper.getDoubleSafe(data.get(data.size() - 1));
	}

}
